Skip to content

feat: integrate BountyTags into CreatorBountyCard and ContributorProfile#810

Closed
LaphoqueRC wants to merge 3 commits intoSolFoundry:mainfrom
LaphoqueRC:feat/bounty-487-integrate-bounty-tags
Closed

feat: integrate BountyTags into CreatorBountyCard and ContributorProfile#810
LaphoqueRC wants to merge 3 commits intoSolFoundry:mainfrom
LaphoqueRC:feat/bounty-487-integrate-bounty-tags

Conversation

@LaphoqueRC
Copy link
Contributor

Closes #487

Integrates the BountyTags component into two remaining components that were rendering tier/skills manually.

Changes

CreatorBountyCard

  • Added BountyTags with tier, skills, category, and maxSkills={4} above the status/escrow/deadline metadata line
  • Bounty creators now see the same GitHub-label-colored pills as the public bounty board

ContributorProfile

  • Replaced manual tierLabel() + TIER_COLORS inline spans with BountyTags tier pill
  • Recent bounties list now uses consistent bounty pill styling
  • Removed redundant duplicate tier display (was shown twice — in text and as a colored span)

Before / After

CreatorBountyCard — before: no tier/skill pills, only text metadata. After: full BountyTags row.

ContributorProfile — before: T1 · 25,000 FNDRY · Mar 23, 2026 in plain text with custom colors. After: styled T1 pill + 25,000 FNDRY · Mar 23, 2026.

Testing

All frontend tests pass (ESLint, TypeScript, Vitest).

Wallet: HZV6YPdTeJPjPujWjzsFLLKja91K2Ze78XeY8MeFhfK8

@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

Reworks how bounty tier/metadata are rendered in two components. In ContributorProfile.tsx the inline tier label and separate tier span were removed; BountyTags now renders the tier (with skills={[]} and showTier) and a nearby <span> shows bounty.earned.toLocaleString() and the formatted bounty.completedAt date. The local tierLabel helper was deleted and RecentBounty.tier’s type changed from 1 | 2 | 3 to BountyTier. In CreatorBountyCard.tsx BountyTags was added to the card header with showTier, maxSkills={4}, className="mb-2", data-testid="creator-bounty", and fallbacks for tier and skills.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

approved, paid

Suggested reviewers

  • chronoeth-creator
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: integrating the BountyTags component into two specific components.
Description check ✅ Passed The description comprehensively explains the changes, their motivation, and impact across both modified components, directly matching the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@LaphoqueRC
Copy link
Contributor Author

CI failures in this PR are pre-existing repository issues unrelated to this change:

  • Backend Tests (pytest): Pre-existing failures in shared test suite (missing escrow_ledger table, unimplemented service methods approve_submission/dispute_submission, enum mismatches in dispute models, test isolation issues)
  • Contracts Check (Anchor): Pre-existing build failures in the Anchor/Solana contracts suite unrelated to frontend component changes

This PR only modifies frontend components (ContributorProfile.tsx and CreatorBountyCard.tsx) — no backend, database, or contract code was touched. These CI checks fail on all open PRs in the same way.

CodeRabbit found no actionable issues and suggests approved + paid labels.

Closes SolFoundry#487

Replaces inline tier/skill rendering with the reusable BountyTags component:

- CreatorBountyCard: adds tier, skills, and category pills above the
  status/escrow/deadline line for visual consistency with BountyCard
- ContributorProfile: replaces manual tierLabel() + TIER_COLORS inline
  spans with BountyTags tier pill in the recent bounties list

Both components now use the same GitHub-label-colored pills as the
bounty board, providing consistent visual language across the app.

Wallet: HZV6YPdTeJPjPujWjzsFLLKja91K2Ze78XeY8MeFhfK8
@LaphoqueRC LaphoqueRC force-pushed the feat/bounty-487-integrate-bounty-tags branch from c7f47d7 to 9b318fd Compare March 24, 2026 15:57
@LaphoqueRC
Copy link
Contributor Author

Rebased onto the latest upstream/main (includes PR #812 CI fixes: Rust 1.85, SQLite isolation, missing model imports).

The remaining CI failures are pre-existing issues in the upstream repository unrelated to this PR:

Backend Lint (Ruff):

  • tests/test_migration.py:79 — E402 module import not at top
  • tests/test_milestones.py — multiple unused imports (uuid, datetime, sqlalchemy.select, BountyStatus)
  • tests/test_milestones_integration.py — same unused imports
  • tests/test_pipeline.py:584 — F841 unused variable rules
  • tests/test_wallet_connect.py — unused imports (patch, Base)

This PR only modifies frontend/src/components/ContributorProfile.tsx and frontend/src/components/bounties/CreatorBountyCard.tsx — neither of which triggers ruff (Python linter for backend). The lint failures are in test files untouched by this PR.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/ContributorProfile.tsx (1)

116-118: 🛠️ Refactor suggestion | 🟠 Major

Remove unused tierLabel function at lines 116-118.

The tierLabel function is dead code—it is defined but never called anywhere in the codebase. The tier string is constructed inline at line 283 using the template literal \T${bounty.tier}`passed to theBountyTags` component. Remove the function to maintain code cleanliness.

Proposed removal
-function tierLabel(tier: 1 | 2 | 3): string {
-  return `T${tier}`;
-}
-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ContributorProfile.tsx` around lines 116 - 118,
Remove the dead helper function tierLabel (named tierLabel) since the tier
string is built inline and the function is not referenced; delete the function
definition from ContributorProfile.tsx and ensure there are no remaining
references or exports to tierLabel (verify usages aside from the inline template
literal `T${bounty.tier}` passed to BountyTags) so the file compiles cleanly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/ContributorProfile.tsx`:
- Around line 281-291: The code in ContributorProfile rendering uses a manual
string build and cast for the tier and passes an empty skills array to
BountyTags; update the RecentBounty type to use the BountyTier union (or store
tier as 'T1'|'T2'|'T3') so you can pass bounty.tier directly to BountyTags
without `as BountyTier`, and if skills should appear here add a skills field to
RecentBounty and pass it instead of `[]` (or intentionally document/leave
`skills={[]}` if not required); locate the BountyTags usage in
ContributorProfile and the RecentBounty definition and adjust types and prop
usage accordingly to remove the cast and avoid an empty skills prop.

---

Outside diff comments:
In `@frontend/src/components/ContributorProfile.tsx`:
- Around line 116-118: Remove the dead helper function tierLabel (named
tierLabel) since the tier string is built inline and the function is not
referenced; delete the function definition from ContributorProfile.tsx and
ensure there are no remaining references or exports to tierLabel (verify usages
aside from the inline template literal `T${bounty.tier}` passed to BountyTags)
so the file compiles cleanly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e1a4d528-3caf-4e70-b5ab-bd8c5e9a7852

📥 Commits

Reviewing files that changed from the base of the PR and between 9e87284 and 9b318fd.

📒 Files selected for processing (2)
  • frontend/src/components/ContributorProfile.tsx
  • frontend/src/components/bounties/CreatorBountyCard.tsx

…bel helper

- Change RecentBounty.tier from '1 | 2 | 3' to BountyTier so the tier
  can be passed directly to BountyTags without a type cast
- Remove unused tierLabel function (was building 'T${tier}' string
  which is now handled by the BountyTier type itself)
- Drop 'as BountyTier' cast in ContributorProfile render

Addresses code review feedback from coderabbitai.
@LaphoqueRC
Copy link
Contributor Author

Addressed the code review feedback:

  • Removed dead tierLabel helper function — it was building T${tier} but was never called anywhere
  • Changed RecentBounty.tier type from 1 | 2 | 3 to BountyTier — this eliminates the \T${bounty.tier}` as BountyTiercast at the usage site; the tier value is now passed directly toBountyTags`

The remaining CI failures (Backend Tests, Ruff lint, Frontend tsc/build) are pre-existing upstream issues unrelated to this change, as noted in the earlier comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/ContributorProfile.tsx`:
- Around line 284-286: The inline date formatting can produce "Invalid Date" for
malformed bounty.completedAt; update ContributorProfile.tsx to parse and
validate the date before rendering: create a local variable (e.g., parsedDate =
new Date(bounty.completedAt)) and check validity with
isNaN(parsedDate.getTime()) (or similar), then use a fallback string (e.g., "—"
or "Unknown date") when invalid; replace the direct new
Date(...).toLocaleDateString(...) usage in the span with the validated/formatted
value so the UI degrades gracefully for bad input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: aa86a1ae-4151-482c-9d24-ee5889f07a03

📥 Commits

Reviewing files that changed from the base of the PR and between 9b318fd and fa5ea88.

📒 Files selected for processing (1)
  • frontend/src/components/ContributorProfile.tsx

Comment on lines +284 to +286
<span className="text-xs text-gray-500">
{bounty.earned.toLocaleString()} FNDRY · {new Date(bounty.completedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
</span>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a safe fallback for malformed completedAt values.

Inline date parsing has no invalid-date guard, so bad input can render Invalid Date in the activity feed. This should degrade gracefully (e.g., fallback text) to avoid user-facing noise.

As per coding guidelines, "frontend/**: React/TypeScript frontend. Check: ... Error/loading/empty state handling".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/ContributorProfile.tsx` around lines 284 - 286, The
inline date formatting can produce "Invalid Date" for malformed
bounty.completedAt; update ContributorProfile.tsx to parse and validate the date
before rendering: create a local variable (e.g., parsedDate = new
Date(bounty.completedAt)) and check validity with isNaN(parsedDate.getTime())
(or similar), then use a fallback string (e.g., "—" or "Unknown date") when
invalid; replace the direct new Date(...).toLocaleDateString(...) usage in the
span with the validated/formatted value so the UI degrades gracefully for bad
input.

@LaphoqueRC
Copy link
Contributor Author

Fixed the two TypeScript errors causing Frontend Type Check (tsc) and Frontend Build (Next.js) failures:

1. Missing codebaseMapTransformer module (pre-existing upstream issue)

Commits in upstream's Phase 3 integration (5a93431) introduced CodebaseMapVisualization.tsx, NodeDetailPanel.tsx, and useCodebaseMap.ts — all importing from ../../data/codebaseMapTransformer — but the file was never created. Added frontend/src/data/codebaseMapTransformer.ts with full implementations of:

  • formatFileSize — human-readable file size strings
  • extractFileExtensions / extractModuleNames — tree traversal helpers for filter options
  • computeRadialLayout — radial canvas layout algorithm for PositionedNode[]
  • computeDependencyLines — line segments connecting dependency source→target nodes

2. RecentBounty.tier type mismatch

The refactor in this PR changed RecentBounty.tier from 1 | 2 | 3 to BountyTier ('T1' | 'T2' | 'T3'), but ContributorProfilePage.tsx still passed the raw numeric tier from the API response. Added a numericTierMap to convert 1→'T1', 2→'T2', 3→'T3' at the call site.

The remaining CI failures (Backend Tests/Lint, Contracts) are pre-existing upstream issues unrelated to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant